# -*- coding: utf-8 -*-
# This code written by ChanGOGOGO
"""
Lemon后台接口服务
"""
import pymysql
import uvicorn
import requests
from fastapi import FastAPI, BackgroundTasks
from pydantic import BaseModel
from starlette.responses import FileResponse
from export_class.export_ant_data_analysis import ExportAntDataAnalysis
from export_class.export_bad_case_mp3 import ExportBadCaseMP3
from export_class.export_bills_detail import ExportBillsDetail
from export_class.export_black_list import ExportBlackList
from export_class.export_call_error_analysis import ExportCallErrorAnalysis
from export_class.export_callout_history import ExportCallOutHistory
from export_class.export_callout_history_fd import ExportCallOutHistoryFD
from export_class.export_daily_bills import ExportDailyBills
from export_class.export_daily_bills_by_line import ExportDailyBillsByLine
from export_class.export_daily_scene_bills import ExportDailySceneBills
from export_class.export_daily_task_overview import ExportDailyTaskCallOverview
from export_class.export_daily_task_overview_op import ExportDailyTaskCallOverviewOP
from export_class.export_llm_inspection import ExportLLMInspection
from export_class.export_llm_output import ExportLLMOutput
from export_class.export_monthly_bills_by_client_fd import ExportMonthlyBillsByClientFD
from export_class.export_monthly_bills_by_line import ExportMonthlyBillsByLine
from export_class.export_not_dial_data import ExportNotDialData
from export_class.export_monthly_bills_by_client import ExportMonthlyBillsByClient
from export_class.export_task_through_node_analysis import ExportTaskThroughNodeAnalysis
from export_class.export_not_connected_phone import ExportNotConnectedPhone
from util import (
    os,
    logging,
    read_config,
    data2beautify,
    wecom_push_msg,
    time,
    package_file,
    get_time_desc,
    install_package_dir,
    lastst_version,
    excel_save_dir,
    db_ip,
    db_port,
    db_username,
    db_password,
    push_url,
    server_ip,
    server_port,
)

app = FastAPI()


@app.get("/download/Lemon.exe")
def download_lemon():
    """下载Lemon安装包"""
    file_name = "Lemon_install.exe"
    file_path = os.path.join(install_package_dir, file_name)
    return FileResponse(file_path, filename=file_name)


class Item(BaseModel):
    client_version: int


@app.post("/checkUpdate")
def check_update(item: Item):
    """
    检查客户端是否需要更新
    :param item: 客户端当前版本号
    :return: 0-无需更新,1-需要更新
    """
    if item.client_version >= int(lastst_version):
        return 0
    elif item.client_version < int(lastst_version):
        return 1


@app.get("/DownloadFile")
def download_file(file_name: str):
    """下载文件"""
    excel_file_path = os.path.join(excel_save_dir, file_name)
    return FileResponse(path=excel_file_path, filename=file_name)


def back_task(lemon_data):
    data_type = lemon_data.get("data_type")
    business = lemon_data.get("business")
    if data_type == "未拨打数据":
        operate_object = ExportNotDialData(lemon_data)
    elif data_type == "话单明细":
        operate_object = ExportBillsDetail(lemon_data)
    elif data_type == "呼出历史":
        if business.find("樊登") != -1:  # 樊登业务，调用特殊的呼出历史导出类
            operate_object = ExportCallOutHistoryFD(lemon_data)
        else:
            operate_object = ExportCallOutHistory(lemon_data)
    elif data_type == "每日通话时长":
        operate_object = ExportDailyBills(lemon_data)
    elif data_type == "每日场景通话时长":
        operate_object = ExportDailySceneBills(lemon_data)
    elif data_type == "话单日结(线路商)":
        operate_object = ExportDailyBillsByLine(lemon_data)
    elif data_type == "话单月结(客户侧)":
        if business.find("樊登") == -1:  # 非樊登业务
            operate_object = ExportMonthlyBillsByClient(lemon_data)
        else:
            operate_object = ExportMonthlyBillsByClientFD(lemon_data)
    elif data_type == "话单月结(线路商)":
        operate_object = ExportMonthlyBillsByLine(lemon_data)
    elif data_type == "呼出黑名单":
        operate_object = ExportBlackList(lemon_data)
    elif data_type == "拨打数据分析(蚂蚁)":
        operate_object = ExportAntDataAnalysis(lemon_data)
    elif data_type == "大模型质检":
        operate_object = ExportLLMInspection(lemon_data)
    elif data_type == "BadCase录音":
        operate_object = ExportBadCaseMP3(lemon_data)
    elif data_type == "每日任务拨打概况":
        operate_object = ExportDailyTaskCallOverview(lemon_data)
    elif data_type == "通话记录大模型出参":
        operate_object = ExportLLMOutput(lemon_data)
    elif data_type == "任务流经节点数据分析":
        operate_object = ExportTaskThroughNodeAnalysis(lemon_data)
    elif data_type == "每日任务拨打概况(欧派)":
        operate_object = ExportDailyTaskCallOverviewOP(lemon_data)
    elif data_type == "未接通名单":
        operate_object = ExportNotConnectedPhone(lemon_data)
    else:
        operate_object = ExportCallErrorAnalysis(lemon_data)
    export_start_time = time.time()
    res = operate_object.export()
    export_end_time = time.time()
    export_take_time = export_end_time - export_start_time
    export_take_time_desc = get_time_desc(export_take_time)
    logging.info(f"exportData接口响应：\n{data2beautify(res)}")
    code = res.get("code")
    if code == 0:
        res_data_type = res.get("res_data_type")
        if res_data_type == "text":
            text = res.get("text")
            wecom_push_msg(push_url, text)
        else:  # 如果接口响应中得到数据类型data_type是None，就认为导出的是excel文件
            excel_names = res.get("excel_names")
            wecom_msg = [
                f"🎉 <font color=red>**{business}**</font>的<font color=green>{data_type}</font>已成功导出（7天内可下载），处理耗时{export_take_time_desc}，请及时下载："
            ]
            if len(excel_names) == 1:  # 单个excel文件直接下载
                download_url = f"http://{server_ip}:{server_port}/DownloadFile?file_name={excel_names[0]}"
                wecom_msg.append(f"[{excel_names[0]}]({download_url})")
            else:  # 多个excel文件打压缩包
                excel_absolute_paths = list()
                for excel_name in excel_names:
                    excel_absolute_path = os.path.join(excel_save_dir, excel_name)
                    excel_absolute_paths.append(excel_absolute_path)
                now_time = time.strftime("%Y%m%d%H%M%S")
                zip_name = f"{business}_{data_type}_{now_time}.zip"
                zip_path = os.path.join(excel_save_dir, zip_name)
                package_file(excel_absolute_paths, zip_path)
                download_url = f"http://{server_ip}:{server_port}/DownloadFile?file_name={zip_name}"
                wecom_msg.append(f"[{zip_name}]({download_url})")
            wecom_push_msg(push_url, msg="\n".join(wecom_msg))
    else:
        msg = res.get("msg")
        wecom_push_msg(push_url, msg)
    return res


def check_lemon_data(lemon_data):
    """Lemon客户端数据校验"""
    target_datas = lemon_data.get("target_datas")
    data_type = lemon_data.get("data_type")
    company_id = lemon_data.get("company_id")
    task_type = lemon_data.get("task_type")
    start_time = lemon_data.get("start_time")
    end_time = lemon_data.get("end_time")
    business = lemon_data.get("business")
    msg = ""
    if bool(company_id) is False:
        msg = f"<font color=red>请选择所属账号！</font>"
    elif bool(business) is False:
        msg = f"<font color=red>请选择业务名称！</font>"
    elif bool(data_type) is False:
        msg = f"<font color=red>请选择数据类型！</font>"
    else:
        if data_type == "未拨打数据":
            if task_type == "已完成任务":
                if start_time > end_time:
                    msg = f"<font color=red>开始时间不得晚于结束时间！</font>"
            if bool(target_datas) is False:
                msg = f"<font color=red>请在目标数据中输入至少一个任务ID！</font>"
        elif data_type == "话单明细":
            if start_time > end_time:
                msg = f"<font color=red>开始时间不得晚于结束时间！</font>"
        elif data_type == "意向数据":
            if start_time > end_time:
                msg = f"<font color=red>开始时间不得晚于结束时间！</font>"
        elif data_type == "呼出历史":
            if start_time > end_time:
                msg = f"<font color=red>开始时间不得晚于结束时间！</font>"
        elif data_type == "每日通话时长":
            if start_time > end_time:
                msg = f"<font color=red>开始时间不得晚于结束时间！</font>"
        elif data_type == "每日场景通话时长":
            if start_time > end_time:
                msg = f"<font color=red>开始时间不得晚于结束时间！</font>"
        elif data_type == "任务流经节点数据分析":
            if start_time > end_time:
                msg = f"<font color=red>开始时间不得晚于结束时间！</font>"
        elif data_type == "话单日结(线路商)":
            if start_time > end_time:
                msg = f"<font color=red>开始时间不得晚于结束时间！</font>"
        elif data_type == "话单月结(客户侧)":
            if start_time > end_time:
                msg = f"<font color=red>开始时间不得晚于结束时间！</font>"
        elif data_type == "话单月结(线路商)":
            if start_time > end_time:
                msg = f"<font color=red>开始时间不得晚于结束时间！</font>"
        elif data_type == "话单月结(线路商)":
            if start_time > end_time:
                msg = f"<font color=red>开始时间不得晚于结束时间！</font>"
        elif data_type == "通话异常分析":
            if start_time > end_time:
                msg = f"<font color=red>开始时间不得晚于结束时间！</font>"
        elif data_type == "通话异常分析":
            if start_time > end_time:
                msg = f"<font color=red>开始时间不得晚于结束时间！</font>"
        elif data_type == "拨打数据分析(蚂蚁)":
            if start_time > end_time:
                msg = f"<font color=red>开始时间不得晚于结束时间！</font>"
        elif data_type == "大模型质检":
            if start_time > end_time:
                msg = f"<font color=red>开始时间不得晚于结束时间！</font>"
        elif data_type == "BadCase录音":
            if start_time > end_time:
                msg = f"<font color=red>开始时间不得晚于结束时间！</font>"
            if bool(target_datas) is False:
                msg = f"<font color=red>请在目标数据中输入至少一个caseId！</font>"
        elif data_type == "未接通名单":
            if start_time > end_time:
                msg = f"<font color=red>开始时间不得晚于结束时间！</font>"
            if bool(target_datas) is False:
                msg = f"<font color=red>请在目标数据中输入至少一个场景！</font>"
    if msg == "":
        return {"result": True, "msg": msg}
    else:
        return {"result": False, "msg": msg}


@app.post("/exportData")
def export_data(background_tasks: BackgroundTasks, lemon_data: dict):
    """导出数据"""
    data_type = lemon_data.get("data_type")
    business = lemon_data.get("business")
    logging.info(f"导出接口收到请求：\n{data2beautify(lemon_data)}")
    check_client_data = check_lemon_data(lemon_data)
    check_result = check_client_data.get("result")
    if check_result:
        background_tasks.add_task(back_task, lemon_data)
        msg = (
            f"后台正在处理“{business}”的【{data_type}】，请留意Lemon企微群的处理结果！"
        )
        res = {"code": 0, "excel_names": None, "msg": msg}
        return res
    else:
        msg = check_client_data.get("msg")
        res = {"code": 1, "excel_names": None, "msg": msg}
        return res


@app.get("/queryAccount")
def query_account():
    conn = pymysql.connect(
        host=db_ip, port=db_port, user=db_username, passwd=db_password, charset="utf8"
    )
    cursor = conn.cursor()
    query_account_sql = (
        "select user_name,company_id from yicall_business.yicall_aiforce_user where company_id >= 1000 "
        "order by company_id;"
    )
    logging.info(f"查询账号信息SQL：\n{query_account_sql}")
    cursor.execute(query_account_sql)
    query_account_result = cursor.fetchall()
    if len(query_account_result) >= 1:
        account_info = {}
        for account, company_id in query_account_result:
            account_info[account] = {"company_id": company_id, "business_info": {}}
            query_business_sql = f"""select business_id,business_name from yicall_{company_id}.call_business 
            order by business_id;"""
            cursor.execute(query_business_sql)
            query_business_result = cursor.fetchall()
            for business_id, business_name in query_business_result:
                account_info[account]["business_info"].update(
                    {business_name: business_id}
                )
        # 关闭数据库
        cursor.close()
        conn.close()
        return {"code": 0, "msg": None, "data": account_info}
    else:
        # 关闭数据库
        cursor.close()
        conn.close()
        return {
            "code": 1,
            "msg": "<font color=red>没有查询到账号信息</font>",
            "data": None,
        }


@app.get("/queryDataType")
def query_data_type():
    """获取Lemon客户端数据类型下拉框可选项"""
    client_interaction_info = read_config("./config/client_interaction.yaml")
    data_type_list = client_interaction_info.keys()
    return list(data_type_list)


@app.post("/queryClientInteraction")
def query_client_interaction(data_type):
    """获取Lemon客户端交互"""
    client_interaction_info = read_config("./config/client_interaction.yaml")
    interaction = {}
    data_type_interaction = client_interaction_info.get(data_type)
    if data_type_interaction:
        interaction = data_type_interaction
    return interaction


@app.get("/getQuote")
def get_quote():
    try:
        res = requests.get("https://v1.hitokoto.cn")
        if res.status_code == 200:
            res_data = res.json()
            hitokoto = res_data.get("hitokoto")
            from_where = res_data.get("from")
            from_who = res_data.get("from_who")
            if from_who is None:
                from_who = "佚名"
            return f"{hitokoto} 丨《{from_where}》 - {from_who}"
    except Exception as reason:
        return reason


if __name__ == "__main__":
    uvicorn.run(
        app="lemon_server_es:app", host=server_ip, port=server_port, reload=False
    )
